package com.kinyx.framework.exception;

import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import com.kinyx.framework.annotation.assist.CanNotNull;
import com.kinyx.framework.annotation.assist.CanNull;
import com.kinyx.framework.annotation.assist.Note;
import com.kinyx.framework.annotation.assist.ReturnNotNull;

import lombok.Getter;

/**
 * 运行时异常
 */
@Getter
@SuppressWarnings("serial")
public class KRuntimeException extends RuntimeException {

	// ===================================================== field ===================================================== //
	/** 错误编码 */
	private final IErrorCode errorCode;
	/** 国际化类型 */
	private Locale locale;
	/** 参数 */
	private Map<String, Object> params;

	// ===================================================== construct ===================================================== //
	/**
	 * 构造方法
	 * @param errorCode 错误编码
	 * @param cause 异常对象
	 */
	public KRuntimeException(@CanNotNull final Throwable cause, @CanNotNull final IErrorCode errorCode) {
		super(cause);
		this.errorCode = errorCode;
	}

	/**
	 * 构造方法
	 * @param cause 异常对象
	 */
	public KRuntimeException(@CanNotNull final Throwable cause) {
		super(cause);
		this.errorCode = new ErrorCode(cause);
	}

	/**
	 * 构造方法
	 * @param errorCode 错误编码
	 */
	public KRuntimeException(@CanNotNull final IErrorCode errorCode) {
		super();
		this.errorCode = errorCode;
	}

	// ===================================================== setter ===================================================== //
	/**
	 * 设置国际化类型
	 * @param locale 国际化类型
	 * @return 本对象
	 */
	@ReturnNotNull
	@Note("return this;")
	public KRuntimeException locale(@CanNull final Locale locale) {
		this.locale = locale;
		return this;
	}

	/**
	 * 设置参数
	 * @param key 键
	 * @param value 值
	 * @return 本对象
	 */
	@ReturnNotNull
	@Note("return this;")
	public KRuntimeException param(@CanNull final String key, @CanNull final Object value) {
		if (this.params == null) { this.params = new HashMap<>(); }
		this.params.put(key, value);
		return this;
	}

	// ===================================================== message ===================================================== //
	@ReturnNotNull
	@Override
	public String getMessage() {
		return this.errorCode.getErrorMessage(this.locale, this.params);
	}

}
